home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Ports / alfa / stdwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  10.1 KB  |  585 lines  |  [TEXT/????]

  1. /* TERMCAP STDWIN -- BASIC ROUTINES. */
  2.  
  3. #include "alfa.h"
  4.  
  5. #if defined(unix) || defined(AMOEBA)
  6. #define DO_SIGNAL
  7. #define DO_SYSTEM
  8. #endif
  9.  
  10. #ifdef DO_SIGNAL
  11. #include <sys/types.h>
  12. #include <signal.h>
  13. #include "sigtype.h"
  14. static SIGTYPE handler(); /* Forward */
  15. #endif
  16.  
  17. int lines, columns;
  18.  
  19. /*ARGSUSED*/
  20. void
  21. winitargs(pargc, pargv)
  22.     int *pargc;
  23.     char ***pargv;
  24. {
  25.     wargs(pargc, pargv);
  26.     winit();
  27. }
  28.  
  29. /*ARGSUSED*/
  30. void
  31. wargs(pargc, pargv)
  32.     int *pargc;
  33.     char ***pargv;
  34. {
  35. }
  36.  
  37. /* Initialization call.
  38.    Should be called only once, before any others.
  39.    Will exit when the initialization fails. */
  40.  
  41. void
  42. winit()
  43. {
  44.     int flags;
  45.     int err;
  46.     
  47. #ifdef DO_SIGNAL
  48.     (void) signal(SIGINT, handler);
  49. #ifdef NDEBUG
  50.     (void) signal(SIGQUIT, handler);
  51. #endif
  52.     (void) signal(SIGILL, handler);
  53.     (void) signal(SIGIOT, handler);
  54.     (void) signal(SIGEMT, handler);
  55.     (void) signal(SIGFPE, handler);
  56.     (void) signal(SIGBUS, handler);
  57.     (void) signal(SIGSEGV, handler);
  58.     (void) signal(SIGSYS, handler);
  59.     (void) signal(SIGTERM, handler);
  60. #endif /* DO_SIGNAL */
  61.     
  62.     getttykeydefs(0);    /* File descriptor 0 */
  63.     err= trmstart(&lines, &columns, &flags);
  64.     if (err != 0) {
  65.         fprintf(stderr, "STDWIN: trmstart error %d\n", err);
  66.         exit(2);
  67.     }
  68.     gettckeydefs();
  69.     if (lines > MAXLINES)
  70.         lines= MAXLINES;
  71.     trmputdata(0, lines-1, 0, "", (char *)0);
  72.     initsyswin();
  73.     _winitmenus();
  74. }
  75.  
  76. /* Termination call.
  77.    Should be called before the program exits
  78.    (else the terminal will be left in almost raw mode). */
  79.  
  80. void
  81. wdone()
  82. {
  83.     if (lines > 0) {
  84.         /* Move cursor to last screen line. */
  85.         trmputdata(lines-1, lines-1, 0, "", (char *)0);
  86.         trmsync(lines-1, 0);
  87.     }
  88.     lines= 0;
  89.     trmend();
  90. }
  91.  
  92. #ifdef DO_SIGNAL
  93.  
  94. /* Signal handler.
  95.    Print a message and exit. */
  96.  
  97. static SIGTYPE
  98. handler(sig)
  99.     int sig;
  100. {
  101.     wdone();
  102.     signal(sig, SIG_DFL);
  103.     kill(0, sig);        /* Kill all others in our process group */
  104.     kill(getpid(), sig);    /* Commit suicide */
  105.     /* (On BSD, the signal is delivered to us only after we return.) */
  106. }
  107.  
  108. #endif /* DO_SIGNAL */
  109.  
  110. /* Essential data structures. */
  111.  
  112. WINDOW winlist[MAXWINDOWS] /* = {FALSE, ...}, ... */;
  113.  
  114. WINDOW *wasfront;    /* What the application thinks is active */
  115. WINDOW *front;        /* The window that is really active */
  116.     /* If these are not equal, an activate or deactivate event
  117.        will be generated by wevent before anything else. */
  118.  
  119. char uptodate[MAXLINES] /* = FALSE, ... */;
  120.  
  121. /* Open a window. */
  122.  
  123. WINDOW *
  124. wopen(title, drawproc)
  125.     char *title;
  126.     void (*drawproc)();
  127. {
  128.     int id;
  129.     WINDOW *win;
  130.     
  131.     for (win= &winlist[0]; win < &winlist[MAXWINDOWS]; ++win) {
  132.         if (!win->open)
  133.             break;
  134.     }
  135.     id= win - &winlist[0];
  136.     if (id >= MAXWINDOWS)
  137.         return NULL;    /* Too many windows open */
  138.     win->open= TRUE;
  139.     _wreshuffle();
  140.     win->resized = FALSE;    /* Don't begin with a redraw event */
  141.     win->tag= 0;
  142.     win->drawproc= drawproc;
  143.     win->title= strdup(title);
  144.     win->attr= wattr;
  145.     
  146.     win->offset= -win->top;
  147.     win->curh= win->curv= -1;
  148.     win->timer= 0;
  149.     
  150.     initmenubar(&win->mbar);
  151.     
  152.     front= win;
  153.     return win;
  154. }
  155.  
  156. /* Divide the available lines over the available windows.
  157.    Line 0 is for window 0, the system window, and is different:
  158.    it has no title, and is always one line high, except when it's
  159.    the only window. */
  160.  
  161. void
  162. _wreshuffle()
  163. {
  164.     int nwins= 0;
  165.     int nlines= lines;
  166.     int top= 0;
  167.     WINDOW *win;
  168.     
  169.     /* Count open windows. */
  170.     for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  171.         if (win->open)
  172.             ++nwins;
  173.     }
  174.     /* Assign each open window its share of the screen. */
  175.     for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  176.         if (win->open) {
  177.             int i= nlines/nwins;    /* This window's share */
  178.             int id= win - winlist;
  179. #ifdef LM_S_PROB
  180.             int oldtop= win->top, oldbot= win->bottom;
  181.             int dv, scrbot;
  182. #endif
  183.             /* Cause redraw event for old title position: */
  184.             if (win->top > 0)
  185.                 uptodate[win->top-1]= FALSE;
  186.             if (id == 0) {    /* System window */
  187.                 win->top= top;
  188.                 if (nwins > 1)
  189.                     i=1;
  190.             }
  191.             else
  192.                 win->top= top+1;
  193.             win->bottom= top + i;
  194.             nlines -= i;
  195.             --nwins;
  196. #ifndef LM_S_PROB
  197.             /* This is overkill;
  198.                we should try not cause a redraw of all lines! */
  199.             for (i= top; i < win->bottom; ++i) {
  200.                 uptodate[i]= FALSE;
  201.             }
  202. #else
  203.             /* LM's probeersel */
  204.             dv= oldtop-win->top;
  205.             scrbot=win->bottom;
  206.             if (oldbot-dv < scrbot) scrbot=oldbot-dv;
  207.             scrollupdate(win->top, scrbot, dv);
  208.             trmscrollup(win->top, scrbot-1, dv);
  209.             for (i= top; i < win->bottom; ++i)
  210.                 if (!(win->top <= i && i < scrbot ||
  211.                       win->top <= i+dv && i+dv < scrbot))
  212.                 uptodate[i]= FALSE;
  213. #endif
  214.             top= win->bottom;
  215.             /* Cause redraw event for new title position: */
  216.             if (win->top > 0)
  217.                 uptodate[win->top-1]= FALSE;
  218.             /* Cause resize event: */
  219.             win->resized= TRUE;
  220.             /* Scroll back if negative line numbers visible: */
  221.             if (win->top + win->offset < 0)
  222.                 wshow(win, 0, 0,
  223.                     columns, win->bottom - win->top);
  224. #if 0 /* We don't really want to for showing the caret... */
  225.             /* Show caret: */
  226.             if (win->curv >= 0)
  227.                 wshow(win, win->curh, win->curv,
  228.                     win->curh, win->curv);
  229. #endif
  230.         }
  231.     }
  232. }
  233.  
  234. /* Close a window. */
  235.  
  236. void
  237. wclose(win)
  238.     WINDOW *win;
  239. {
  240.     int id= win - winlist;
  241.     
  242.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  243.         return;
  244.     killmenubar(&win->mbar);
  245.     if (win == wasfront)
  246.         wasfront= NULL;
  247.     if (win == front)
  248.         front= NULL;
  249.     win->open= FALSE;
  250.     if (win->title != NULL) {
  251.         free(win->title);
  252.         win->title= NULL;
  253.     }
  254.     _wreshuffle();
  255.     /* Select another window. */
  256.     if (front == NULL) {
  257.         /* Search below the window we just closed. */
  258.         for (; win < &winlist[MAXWINDOWS]; ++win) {
  259.             if (win->open) {
  260.                 front= win;
  261.                 break; /* First hit is OK */
  262.             }
  263.         }
  264.         if (front == NULL) {
  265.             /* Try searching above it. */
  266.             for (win= winlist+1; win < &winlist[MAXWINDOWS];
  267.                                 ++win) {
  268.                 if (win->open)
  269.                     front= win;
  270.                 /* NO break -- we need the last hit */
  271.             }
  272.         }
  273.         if (front == NULL) {
  274.             /* Exasperation time. */
  275.             front= &winlist[0]; /* The system window */
  276.         }
  277.         _wnewtitle(front); /* Make sure the title is redrawn */
  278.     }
  279. }
  280.  
  281. /* Dummies for functions not supported by this version. */
  282.  
  283. /*ARGSUSED*/
  284. void
  285. wsetdefwinpos(h, v)
  286.     int h, v;
  287. {
  288. }
  289.  
  290. /*ARGSUSED*/
  291. void
  292. wsetdefwinsize(width, height)
  293.     int width, height;
  294. {
  295. }
  296.  
  297. /*ARGSUSED*/
  298. void
  299. wsetmaxwinsize(width, height)
  300.     int width, height;
  301. {
  302. }
  303.  
  304. /*ARGSUSED*/
  305. void
  306. wsetdefscrollbars(width, height)
  307.     int width, height;
  308. {
  309. }
  310.  
  311. void
  312. wgetdefwinpos(ph, pv)
  313.     int *ph, *pv;
  314. {
  315.     *ph = *pv = 0;
  316. }
  317.  
  318. void
  319. wgetdefwinsize(ph, pv)
  320.     int *ph, *pv;
  321. {
  322.     *ph = *pv = 0;
  323. }
  324.  
  325. void
  326. wgetdefscrollbars(ph, pv)
  327.     int *ph, *pv;
  328. {
  329.     *ph = *pv = 0;
  330. }
  331.  
  332. /* Make a window the active window. */
  333.  
  334. void
  335. wsetactive(win)
  336.     WINDOW *win;
  337. {
  338.     int id= win - winlist;
  339.     
  340.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  341.         return;
  342.     _wnewtitle(front);
  343.     front= win;
  344.     _wnewtitle(front);
  345. }
  346.  
  347. /* Select next, previous window.
  348.    Note: these will never select the system window unless it is already
  349.    selected (which can only occur if there are no other windows open). */
  350.  
  351. void
  352. _wselnext()
  353. {
  354.     WINDOW *win;
  355.     
  356.     for (win= front+1; win < &winlist[MAXWINDOWS]; ++win) {
  357.         if (win->open) {
  358.             wsetactive(win);
  359.             return;
  360.         }
  361.     }
  362.     for (win= winlist+1; win < front; ++win) {
  363.         if (win->open) {
  364.             wsetactive(win);
  365.             return;
  366.         }
  367.     }
  368. }
  369.  
  370. void
  371. _wselprev()
  372. {
  373.     WINDOW *win;
  374.     
  375.     for (win= front-1; win > winlist; --win) {
  376.         if (win->open) {
  377.             wsetactive(win);
  378.             return;
  379.         }
  380.     }
  381.     for (win= &winlist[MAXWINDOWS-1]; win > front; --win) {
  382.         if (win->open) {
  383.             wsetactive(win);
  384.             return;
  385.         }
  386.     }
  387. }
  388.  
  389. /* Force a redraw of the entire screen.
  390.    (This routine only sets 'invalid' bits for all lines;
  391.    the actual redraw is done later in wgetevent or wupdate.) */
  392.  
  393. void
  394. _wredraw()
  395. {
  396.     int i;
  397.     
  398.     for (i= 0; i < lines; ++i)
  399.         uptodate[i]= FALSE;
  400.     _wreshuffle();
  401.     trmundefined();
  402.     trmputdata(0, lines-1, 0, "", (char *)0);
  403. }
  404.  
  405. /* Temporarily restore cooked tty mode. */
  406.  
  407. _wcooked()
  408. {
  409.     trmputdata(lines-1, lines-1, 0, "", (char *)0);
  410.     trmsync(lines-1, 0);
  411.     trmend();
  412. }
  413.  
  414. /* Back to window mode.
  415.    If 'wait' flag is set, wait until a character is typed before
  416.    continuing. clearing the screen. */
  417.  
  418. _wstdwin(wait)
  419.     bool wait;
  420. {
  421.     int flags;
  422.     
  423.     if (wait) {
  424.         printf("\nCR to continue... ");
  425.         fflush(stdout);
  426.     }
  427.     (void) trmstart(&lines, &columns, &flags);
  428.     if (wait)
  429.         (void) trminput();
  430.     _wredraw();
  431.     wmessage((char *)NULL); /* Reset menu bar */
  432. }
  433.  
  434. /* Suspend the process (BSD Unix only). */
  435.  
  436. void
  437. _wsuspend()
  438. {
  439.     _wcooked();
  440.     trmsuspend();
  441.     _wstdwin(FALSE);
  442. }
  443.  
  444. /* Execute a shell command, if possible and necessary outside the window
  445.    manager.  If the 'wait' parameter is set, the window manager pauses
  446.    until a character is typed before continuing. */
  447.  
  448. int
  449. wsystem(cmd, wait)
  450.     char *cmd;
  451.     bool wait;
  452. {
  453. #ifdef DO_SYSTEM
  454.     int status;
  455.     _wcooked();
  456.     status= system(cmd);
  457.     _wstdwin(wait);
  458.     return status;
  459. #else
  460.     return -1;
  461. #endif
  462. }
  463.  
  464. /* Return active window. */
  465.  
  466. WINDOW *
  467. wgetactive()
  468. {
  469.     return front;
  470. }
  471.  
  472. /* Change a window's title. */
  473.  
  474. void
  475. wsettitle(win, title)
  476.     WINDOW *win;
  477.     char *title;
  478. {
  479.     if (win->title != NULL)
  480.         free(win->title);
  481.     win->title= strdup(title);
  482.     _wnewtitle(win);
  483. }
  484.  
  485. /* Change the mouse cursor -- dummy */
  486.  
  487. /*ARGSUSED*/
  488. void
  489. wsetwincursor(win, cursor)
  490.     WINDOW *win;
  491.     CURSOR *cursor;
  492. {
  493. }
  494.  
  495. /* Fetch a mouse cursor -- always return NULL */
  496.  
  497. /*ARGSUSED*/
  498. CURSOR *
  499. wfetchcursor(name)
  500.     char *name;
  501. {
  502.     return NULL;
  503. }
  504.  
  505. /* Set a window's extent (document size). Not implemented here. */
  506.  
  507. /*ARGSUSED*/
  508. void
  509. wsetdocsize(win, width, height)
  510.     WINDOW *win;
  511.     int width, height;
  512. {
  513. }
  514.  
  515. /*ARGSUSED*/
  516. void
  517. wgetdocsize(win, pwidth, pheight)
  518.     WINDOW *win;
  519.     int *pwidth, *pheight;
  520. {
  521.     *pwidth = *pheight = 0;
  522. }
  523.  
  524. /* Get a window's origin with respect to document. */
  525.  
  526. void
  527. wgetorigin(win, ph, pv)
  528.     WINDOW *win;
  529.     int *ph, *pv;
  530. {
  531.     *ph= 0;
  532.     *pv= win->top + win->offset;
  533. }
  534.  
  535. /* Get a window's origin with respect to screen. */
  536.  
  537. void
  538. wgetwinpos(win, ph, pv)
  539.     WINDOW *win;
  540.     int *ph, *pv;
  541. {
  542.     *ph= 0;
  543.     *pv= win->top;
  544. }
  545.  
  546. /* Get a window's window size. */
  547.  
  548. void
  549. wgetwinsize(win, pwidth, pheight)
  550.     WINDOW *win;
  551.     int *pwidth, *pheight;
  552. {
  553.     *pwidth= columns;
  554.     *pheight= win->bottom - win->top;
  555. }
  556.  
  557. /* Get the screen size in pixels. */
  558.  
  559. void
  560. wgetscrsize(ph, pv)
  561.     int *ph, *pv;
  562. {
  563.     *ph= columns;
  564.     *pv= lines;
  565. }
  566.  
  567. /* Get the screen size in mm.
  568.    Of course we don't know it; we pretend that the average character
  569.    is 3 mm wide and 6 mm high, which is a reasonable approximation
  570.    of reality on my terminal (an HP2621). */
  571.  
  572. void
  573. wgetscrmm(ph, pv)
  574.     int *ph, *pv;
  575. {
  576.     *ph= columns * 3;
  577.     *pv= lines * 6;
  578. }
  579.  
  580. void
  581. wfleep()
  582. {
  583.     trmbell();
  584. }
  585.